//
// Created by Martin on 2022/10/1.
//

#include <iostream>

using namespace std;

#if 0
template<typename T>
struct add_const_ref
{
    typedef T const& type;
};

template<typename T>
struct add_const_ref<T&>
{
    typedef T& type;
};
#else
template<bool, typename T>
struct add_const_ref_detail{};        // add_const_ref_detail主模板

template<typename T>
struct add_const_ref
{
    typedef typename add_const_ref_detail<std::is_reference<T>::value, T>::type type; // 根据T是否为引用类型, 进行dispatch
};

template<typename T>
struct add_const_ref_detail<true, T>  // add_const_ref_detail偏特化版本
{
    typedef typename std::remove_reference<T>::type type;
};

template<typename T>
struct add_const_ref_detail<false, T> // add_const_ref_detail偏特化版本
{
    typedef typename std::add_lvalue_reference<typename std::add_const<T>::type>::type type;
};
#endif

static void test_add_const_ref()
{
    cout << std::boolalpha;
    cout << std::is_same<add_const_ref<int>::type, int>::value << endl;        // false
    cout << std::is_same<add_const_ref<int>::type, const int&>::value << endl; // true
    cout << "-----" << endl;
    cout << std::is_same<add_const_ref<int&>::type, int&>::value << endl;      // true
}

int main()
{
    test_add_const_ref();
    return 0;
}